/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wave;
import base.*;
import communicator.CommunicationProcessor;
/**
 *
 * @author Tue
 */
public class WaveInterpreter {
    private KN kn;
    private TrackForest trackForest;
    private SynchronousQueue<Wave> waveQueue;
    private SynchronousQueue trackQueue;
    private SynchronousQueue propagationQueue;
    
    private TrackProcessor trackProcessor;
    private WaveProcessor waveProcessor;
    private CommunicationProcessor comProcessor;

    private static WaveInterpreter singleton;

    private boolean start = false;
    
    public WaveInterpreter(){
        kn = new KN();
        trackForest = new TrackForest();
        waveQueue = new SynchronousQueue<Wave>();
        trackQueue = new SynchronousQueue();
        propagationQueue = new SynchronousQueue();
        
        trackProcessor = new TrackProcessor(this);
        waveProcessor = new WaveProcessor(this);
        comProcessor = new CommunicationProcessor(propagationQueue);
    }
    public WaveInterpreter(KN kn){
        this.kn = kn;
        this.trackForest = new TrackForest();
        waveQueue = new SynchronousQueue<Wave>();
        trackQueue = new SynchronousQueue();
        propagationQueue = new SynchronousQueue();

        trackProcessor = new TrackProcessor(this);
        waveProcessor = new WaveProcessor(this);
        comProcessor = new CommunicationProcessor(propagationQueue);
    }

    public static WaveInterpreter getInstance(){
        if(singleton == null){
            singleton = new WaveInterpreter();
        } 
        return singleton;
    }
    public void start(){
        if(!start) {
            System.out.println("[Wave Interpreter] starting ...");
            waveProcessor.start();
            trackProcessor.start();
            comProcessor.start();
        }
    }

    public SynchronousQueue getPropagationQueue() {
        return propagationQueue;
    }

    public SynchronousQueue getTrackQueue() {
        return trackQueue;
    }

    public SynchronousQueue<Wave> getWaveQueue() {
        return waveQueue;
    }

    public KN getKN(){
        return this.kn;
    }

    public TrackForest getTrackForest() {
        return trackForest;
    }

    public void injectWave(String waveString){
        Wave w = new Wave(waveString, new WaveEnvironment());
        this.waveQueue.incoming(w);
    }
    public void injectWave(String waveString, int color) {
        Wave w = new Wave(waveString, new WaveEnvironment());
        w.getWaveEnv().setColor(color);
        this.waveQueue.incoming(w);
    }
}
